package com.ihealthway.all.task;

import com.ihealthway.all.groupbuy.vo.AdminLog;
import org.nutz.dao.Dao;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.log.Log;
import org.nutz.log.Logs;
import org.nutz.mvc.Mvcs;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;

/**
 * Use queue and threads async system operate log info
 *
 * @author 凡梦星尘(elkan1788@gmail.com)
 */
@IocBean(create="init", depose="close")
public class AsyncOperateLogTask implements Runnable {

    private static final Log logger = Logs.get();

    public static final LinkedBlockingQueue<AdminLog> LOGS_QUEUE = new LinkedBlockingQueue<>();

    private static final ExecutorService ASYNC_SERVICE = Executors.newFixedThreadPool(5);

    @Inject
    private Dao dao;

    private boolean running = true;

    public void init() {
        logger.info("Async system admin operate log task init...");
        ASYNC_SERVICE.submit(Mvcs.getIoc().get(AsyncOperateLogTask.class));
    }

    public void close() throws InterruptedException {

        LOGS_QUEUE.clear();
        running = false;

        if (ASYNC_SERVICE != null && !ASYNC_SERVICE.isShutdown()) {
            ASYNC_SERVICE.shutdown();
            ASYNC_SERVICE.awaitTermination(5, TimeUnit.SECONDS);
        }
    }

    @Override
    public void run() {

        while (running) {
            if (LOGS_QUEUE.isEmpty()) {
                try {
                    Thread.sleep(3 * 1000);
                } catch (InterruptedException e) {
                    logger.error("Sleep wait for log queue failed.", e);
                }
                continue;
            }
            try {
                AdminLog operateLog = LOGS_QUEUE.poll(1, TimeUnit.SECONDS);
                if (operateLog != null) {
                    logger.infof("async system admin[%d] operate log: %s.", operateLog.getSaId(), operateLog.getContent());
                    dao.fastInsert(operateLog);
                }
            } catch (InterruptedException e) {
                logger.error("Poll admin operate log from link queue failed.", e);
            }
        }
    }

}
